﻿using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
using CloudShot.Utils;

namespace CloudShot
{
	static class Program
	{
		private static readonly Mutex Mutex = new Mutex(true, "CloudShot by name1ess0ne");

		[System.Runtime.InteropServices.DllImport("user32.dll")]
		private static extern bool SetProcessDPIAware();

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main()
		{
			string errorFile = AppHelper.ErrorFile;

			Debug.WriteLine("## Error file created: " + errorFile);
			Trace.AutoFlush = true;
			Trace.Listeners.Add(new TextWriterTraceListener(errorFile));

			// Add the event handler for handling UI thread exceptions to the event.
			Application.ThreadException += UIThreadException;
			
			// Set the unhandled exception mode to force all Windows Forms errors to go through
			// our handler.
			Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

			// Add the event handler for handling non-UI thread exceptions to the event. 
			AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

			if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();

			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);

			if (Mutex.WaitOne(TimeSpan.Zero, true))
			{
				Application.Run(new MainForm());
				Mutex.ReleaseMutex();
			}
			else
			{
				MessageBox.Show("CloudShot already running.\nAt the same time may be run only one instance.",
					Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
			}
		}

		private static void UIThreadException(object sender, ThreadExceptionEventArgs e)
		{
			ShowThreadExceptionDialog(Application.ProductName, e.Exception);
			Application.Exit();
		}

		private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
		{
			Exception ex = (Exception)e.ExceptionObject;
			ShowThreadExceptionDialog(Application.ProductName, ex);
			Application.Exit();
		}

		// Creates the error message and displays it.
		private static void ShowThreadExceptionDialog(string title, Exception err)
		{
			ErrorsHelper.TraceError(err);

			string errorMsg = "An application error occurred. Please contact the developer with the following information:\n\n";
			errorMsg = errorMsg + err.Message + "\n\nStack Trace:\n" + err.StackTrace;
			MessageBox.Show(errorMsg, title, MessageBoxButtons.OK, MessageBoxIcon.Stop);
		}
	}
}
